﻿using System;
using System.Data;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

using PlugNT.Common;
using PlugNT.Pack.Editer.Ubb;

namespace PlugNT.Pack.Editer
{

    public class UbbHelper
    {
        private string _Root_Path = ((HttpContext.Current.Request.ApplicationPath == "/") ? "/ubb" : (HttpContext.Current.Request.ApplicationPath + "/ubb"));
        private static RegexOptions options = RegexOptions.IgnoreCase;
        private static Regex[] r = new Regex[20];

        static UbbHelper()
        {
            r[0] = new Regex(@"\s*\[code\]([\s\S]+?)\[\/code\]\s*", options);
            r[1] = new Regex(@"(\[upload=([^\]]{1,4})(,.*?\.[^\]]{1,4})?\])(.*?)(\[\/upload\])", options);
            r[2] = new Regex(@"viewfile.asp\?id=(\d{1,})", RegexOptions.Singleline | RegexOptions.IgnoreCase);
            r[3] = new Regex(@"(\[uploadimage\])(.*?)(\[\/uploadimage\])", options);
            r[4] = new Regex(@"viewfile.asp\?id=(\d{1,})", RegexOptions.Singleline | RegexOptions.IgnoreCase);
            r[5] = new Regex(@"(\[uploadfile\])(.*?)(\[\/uploadfile\])", options);
            r[6] = new Regex(@"viewfile.asp\?id=(\d{1,})", RegexOptions.Singleline | RegexOptions.IgnoreCase);
            r[7] = new Regex(@"(\[upload\])(.*?)(\[\/upload\])", options);
            r[8] = new Regex(@"viewfile.asp\?id=(\d{1,})", RegexOptions.Singleline | RegexOptions.IgnoreCase);
            r[9] = new Regex(@"(\r\n((&nbsp;)|　)+)(?<正文>\S+)", options);
            r[10] = new Regex(@"\s*\[hide\][\n\r]*([\s\S]+?)[\n\r]*\[\/hide\]\s*", RegexOptions.IgnoreCase);
            r[11] = new Regex(@"\[table(?:=(\d{1,4}%?)(?:,([\(\)%,#\w ]+))?)?\]\s*([\s\S]+?)\s*\[\/table\]", options);
            r[12] = new Regex(@"\[media=(\w{1,4}),(\d{1,4}),(\d{1,4})(,(\d))?\]\s*([^\[\<\r\n]+?)\s*\[\/media\]", options);
            r[13] = new Regex(@"\[attach\](\d+)(\[/attach\])*", options);
            r[14] = new Regex(@"\[attachimg\](\d+)(\[/attachimg\])*", options);
            r[15] = new Regex(@"\s*\[free\][\n\r]*([\s\S]+?)[\n\r]*\[\/free\]\s*", RegexOptions.IgnoreCase);
            r[0x10] = new Regex(@"\s*\[hide=(\d+?)\][\n\r]*([\s\S]+?)[\n\r]*\[\/hide\]\s*", RegexOptions.IgnoreCase);
        }

        /// <summary>
        /// 清除[attach][attachimg]标签
        /// </summary>
        /// <param name="sDetail"></param>
        /// <returns></returns>
        private string ClearAttachUbb(string sDetail)
        {
            sDetail = r[13].Replace(sDetail, string.Empty);
            return r[14].Replace(sDetail, string.Empty);
        }

        /// <summary>
        /// 清除UBB标签
        /// </summary>
        /// <param name="sDetail">帖子内容</param>
        /// <returns>帖子内容</returns>
        private string ClearBr(string sDetail)
        {
            return Regex.Replace(sDetail, @"[\r\n]", string.Empty, RegexOptions.IgnoreCase);
        }

        /// <summary>
        /// 该方法已被抽到Utils类中
        /// </summary>
        /// <param name="sDetail">帖子内容</param>
        /// <returns>帖子内容</returns>
        private string ClearUbb(string sDetail)
        {
            return Regex.Replace(sDetail, @"\[[^\]]*?\]", string.Empty, RegexOptions.IgnoreCase);
        }

        /// <summary>
        /// 隐藏[hide]标签中的内容
        /// </summary>
        /// <param name="str">帖子内容</param>
        /// <param name="hide">hide标记</param>
        /// <returns>帖子内容</returns>
        private string HideDetail(string str, int hide, int usercredit)
        {
            if (hide != 0)
            {
                int hidecredits = 0;
                int intTableIndexOf = str.ToLower().IndexOf("[hide");
                while ((intTableIndexOf >= 0) && (str.ToLower().IndexOf("[/hide]") >= 0))
                {
                    Match m = r[10].Match(str);
                    while (m.Success)
                    {
                        if (hide == 1)
                        {
                            str = str.Replace(m.Groups[0].ToString(), "<div class=\"hide\"><div class=\"hidestyle\">***** 该内容需会员回复才可浏览 *****</div></div>");
                        }
                        else
                        {
                            str = str.Replace(m.Groups[0].ToString(), "<div class=\"hide\"><div class=\"hidestyle\">以下内容会员跟帖回复才能看到</div><div class=\"hidetext\"><br />==============================<br /><br />" + m.Groups[1].ToString() + "<br /><br />==============================</div></div>");
                        }
                        m = m.NextMatch();
                    }
                    for (m = r[0x10].Match(str); m.Success; m = m.NextMatch())
                    {
                        hidecredits = TypeConverter.StrToInt(m.Groups[1].ToString());
                        if ((hide != -2) && (usercredit < hidecredits))
                        {
                            str = str.Replace(m.Groups[0].ToString(), "<div class=\"hide\"><div class=\"hidestyle\">***** 该内容需浏览者积分高于" + hidecredits + " 才可浏览 ***** </div></div>");
                        }
                        else
                        {
                            str = str.Replace(m.Groups[0].ToString(), string.Concat(new object[] { "<div class=\"hide\"><div class=\"hidestyle\">以下内容只有在浏览者积分高于 ", hidecredits, " 时才显示</div><div class=\"hidetext\"><br />==============================<br /><br />", m.Groups[2].ToString(), "<br /><br />==============================</div></div>" }));
                        }
                    }
                    if ((intTableIndexOf + 7) > str.Length)
                    {
                        intTableIndexOf = str.ToLower().IndexOf("[table", str.Length);
                    }
                    else
                    {
                        intTableIndexOf = str.ToLower().IndexOf("[table", (int) (intTableIndexOf + 7));
                    }
                }
            }
            return str;
        }

        /// <summary>
        /// 转换code标签
        /// </summary>
        /// <param name="text">帖子内容</param>
        /// <param name="pcodecount">code的数量</param>
        /// <param name="builder">转换后的内容</param>
        /// <returns>帖子内容</returns>
        private string Parsecode(string text, string prefix, ref int pcodecount, int allowhtml, ref StringBuilder builder)
        {
            text = Regex.Replace(text, @"^[\n\r]*([\s\S]+?)[\n\r]*$", "$1", options);
            if (!builder.ToString().Equals(""))
            {
                builder.Append("<>");
            }
            builder.Append("<div class=\"blockcode\"><div id=\"code" + prefix + "_" + ((int) pcodecount).ToString() + "\"><ol>");
            foreach (string str in Utils.SplitString(text, "\r\n"))
            {
                if (allowhtml == 0)
                {
                    builder.Append("<li>" + str + "<br/></li>{rn}");
                }
                else
                {
                    builder.Append("<li>" + str + "<br/></li>\r\n");
                }
            }
            builder.Append("</ol></div><em onclick=\"copycode($('code" + prefix + "_" + ((int) pcodecount).ToString() + "'));\">复制代码</em></div>");
            pcodecount++;
            text = "[\tDISCUZ_CODE_" + prefix + "_" + ((int) pcodecount).ToString() + "\t]";
            return text;
        }

        private string ParseMedia(string type, int width, int height, bool autostart, string url)
        {
            if ("ra,rm,wma,wmv,mp3,mov".IndexOf(type) < 0)
            {
                return "";
            }
            url = url.Replace(@"\\", @"\").Replace("<", string.Empty).Replace(">", string.Empty);
            string mediaid = "media_" + new Random(3).Next();
            switch (type)
            {
                case "ra":
                    return string.Format("<object classid=\"clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA\" width=\"{0}\" height=\"32\"><param name=\"autostart\" value=\"{1}\" /><param name=\"src\" value=\"{2}\" /><param name=\"controls\" value=\"controlpanel\" /><param name=\"console\" value=\"{3}_\" /><embed src=\"{2}\" type=\"audio/x-pn-realaudio-plugin\" controls=\"ControlPanel\" {4} console=\"{3}_\" width=\"{0}\" height=\"32\"></embed></object>", new object[] { width, autostart ? 1 : 0, url, mediaid, autostart ? "autostart=\"true\"" : string.Empty });

                case "rm":
                    return string.Format("<object classid=\"clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA\" width=\"{0}\" height=\"{1}\"><param name=\"autostart\" value=\"{2}\" /><param name=\"src\" value=\"{3}\" /><param name=\"controls\" value=\"imagewindow\" /><param name=\"console\" value=\"{4}_\" /><embed src=\"{3}\" type=\"audio/x-pn-realaudio-plugin\" controls=\"IMAGEWINDOW\" console=\"{4}_\" width=\"{0}\" height=\"{1}\"></embed></object><br /><object classid=\"clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA\" width=\"{0}\" height=\"32\"><param name=\"src\" value=\"{3}\" /><param name=\"controls\" value=\"controlpanel\" /><param name=\"console\" value=\"{4}_\" /><embed src=\"{3}\" type=\"audio/x-pn-realaudio-plugin\" controls=\"ControlPanel\" {5} console=\"{4}_\" width=\"{0}\" height=\"32\"></embed></object>", new object[] { width, height, autostart ? 1 : 0, url, mediaid, autostart ? "autostart=\"true\"" : string.Empty });

                case "wma":
                    return string.Format("<object classid=\"clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6\" width=\"{0}\" height=\"64\"><param name=\"autostart\" value=\"{1}\" /><param name=\"url\" value=\"{2}\" /><embed src=\"{2}\" autostart=\"{1}\" type=\"audio/x-ms-wma\" width=\"{0}\" height=\"64\"></embed></object>", width, autostart ? 1 : 0, url);

                case "wmv":
                    return string.Format("<object classid=\"clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6\" width=\"{0}\" height=\"{1}\"><param name=\"autostart\" value=\"{2}\" /><param name=\"url\" value=\"{3}\" /><embed src=\"{3}\" autostart=\"{2}\" type=\"video/x-ms-wmv\" width=\"{0}\" height=\"{1}\"></embed></object>", new object[] { width, height, autostart ? 1 : 0, url });

                case "mp3":
                    return string.Format("<object classid=\"clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6\" width=\"{0}\" height=\"64\"><param name=\"autostart\" value=\"{1}\"/><param name=\"url\" value=\"{2}\" /><embed src=\"{2}\" autostart=\"{1}\" type=\"application/x-mplayer2\" width=\"{0}\" height=\"64\"></embed></object>", width, autostart ? 1 : 0, url);

                case "mov":
                    return string.Format("<object classid=\"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B\" width=\"{0}\" height=\"{1}\"><param name=\"autostart\" value=\"{2}\" /><param name=\"src\" value=\"{3}\" /><embed controller=\"true\" width=\"{0}\" height=\"{1}\" src=\"{3}\" autostart=\"{2}\"></embed></object>", new object[] { width, height, autostart.ToString().ToLower(), url });
            }
            return string.Empty;
        }

        /// <summary>
        /// 转换表情
        /// </summary>
        /// <param name="sDetail">帖子内容</param>
        /// <param name="__smiliesinfo">表情数组</param>
        /// <param name="smiliesmax">每种表情的最大使用数</param>
        /// <returns>帖子内容</returns>
        private string ParseSmilies(string sDetail)
        {
            string xml_file = this.Root_Path + "/smilies.xml";
            FileInfo fil = new FileInfo(HttpContext.Current.Server.MapPath(xml_file));
            if (fil.Exists)
            {
                DataSet ds = new DataSet();
                ds.ReadXml(HttpContext.Current.Server.MapPath(xml_file));
                DataTable dtb = ds.Tables[0];
                foreach (DataRow dr in dtb.Rows)
                {
                    string img_str = "<img border='0' src='" + this.Root_Path + "/images/smilies/" + dr["imgUrl"].ToString() + "'>";
                    sDetail = sDetail.Replace(dr["code"].ToString(), img_str);
                }
            }
            return sDetail;
        }

        /// <summary>
        /// 转换表格
        /// </summary>
        /// <param name="str">帖子内容</param>
        /// <returns>帖子内容</returns>
        private string ParseTable(string str)
        {
            string stable = "";
            string width = "";
            string bgcolor = "";
            for (int intTableIndexOf = str.ToLower().IndexOf("[table"); (intTableIndexOf >= 0) && (str.ToLower().IndexOf("[/table]") >= 0); intTableIndexOf = str.ToLower().IndexOf("[table", (int) (intTableIndexOf + 7)))
            {
                for (Match m = r[11].Match(str); m.Success; m = m.NextMatch())
                {
                    width = m.Groups[1].ToString();
                    width = Utils.CutString(width, width.Length - 1, width.Length).Equals("%") ? ((Utils.StrToInt(Utils.CutString(width, 0, width.Length - 1), 100) <= 0x62) ? width : "98%") : ((Utils.StrToInt(width, 560) <= 560) ? width : "560");
                    bgcolor = m.Groups[2].ToString();
                    stable = "<table class=\"t_table\" cellspacing=\"1\" cellpadding=\"4\" style=\"";
                    stable = (stable + (width.Equals("") ? "" : ("width:" + width + ";"))) + ("".Equals(bgcolor) ? "" : ("background: " + bgcolor + ";")) + "\">";
                    width = Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(m.Groups[3].ToString(), @"\[td=(\d{1,2}),(\d{1,2})(,(\d{1,4}%?))?\]", "<td colspan=\"$1\" rowspan=\"$2\" width=\"$4\" class=\"t_table\">", options), @"\[tr\]", "<tr>", options), @"\[td\]", "<td>", options), @"\[\/td\]", "</td>", options), @"\[\/tr\]", "</tr>", options), @"\<td\>\<\/td\>", "<td>&nbsp;</td>", options);
                    stable = stable + width + "</table>";
                    str = str.Replace(m.Groups[0].ToString(), stable);
                }
            }
            return str;
        }

        private string ParseUrl(string sDetail)
        {
            sDetail = Regex.Replace(sDetail, @"\[url(?:\s*)\](www\.(.*?))\[/url(?:\s*)\]", "<a href=\"http://$1\" target=\"_blank\">$1</a>", options);
            sDetail = Regex.Replace(sDetail, "\\[url(?:\\s*)\\]\\s*((https?://|ftp://|gopher://|news://|telnet://|rtsp://|mms://|callto://|bctp://|ed2k://|tencent)([^\\[\"']+?))\\s*\\[\\/url(?:\\s*)\\]", "<a href=\"$1\" target=\"_blank\">$1</a>", options);
            sDetail = Regex.Replace(sDetail, "\\[url=www.([^\\[\"']+?)(?:\\s*)\\]([\\s\\S]+?)\\[/url(?:\\s*)\\]", "<a href=\"http://www.$1\" target=\"_blank\">$2</a>", options);
            sDetail = Regex.Replace(sDetail, "\\[url=((https?://|ftp://|gopher://|news://|telnet://|rtsp://|mms://|callto://|bctp://|ed2k://|tencent://)([^\\[\"']+?))(?:\\s*)\\]([\\s\\S]+?)\\[/url(?:\\s*)\\]", "<a href=\"$1\" target=\"_blank\">$4</a>", options);
            return sDetail;
        }

        /// <summary>
        /// 转换自定义标签
        /// </summary>
        /// <param name="sDetail">帖子内容</param>
        /// <param name="__customeditorbuttoninfo">自定义标签数组</param>
        /// <returns>帖子内容</returns>
        private string ReplaceCustomTag(string sDetail, CustomEditorButtonInfo[] customeditorbuttoninfo)
        {
            if (customeditorbuttoninfo != null)
            {
                string replacement = "";
                int b_params = 0;
                for (int i = 0; i < Editors.regexCustomTag.Length; i++)
                {
                    replacement = customeditorbuttoninfo[i].Replacement;
                    b_params = customeditorbuttoninfo[i].Params;
                    for (int k = 0; k < customeditorbuttoninfo[i].Nest; k++)
                    {
                        for (Match m = Editors.regexCustomTag[i].Match(sDetail); m.Success; m = m.NextMatch())
                        {
                            string tempReplacement = replacement.Replace("{1}", m.Groups[m.Groups.Count - 1].ToString());
                            if (b_params > 1)
                            {
                                for (int j = 2; j <= b_params; j++)
                                {
                                    if (m.Groups.Count > j)
                                    {
                                        tempReplacement = tempReplacement.Replace("{" + j + "}", m.Groups[j].ToString());
                                    }
                                }
                            }
                            sDetail = sDetail.Replace(m.Groups[0].ToString(), tempReplacement);
                            sDetail = sDetail.Replace("{RANDOM}", Guid.NewGuid().ToString());
                        }
                    }
                }
            }
            return sDetail;
        }

        /// <summary>
        /// UBB代码处理函数
        /// </summary>
        /// <returns>输出字符串</returns>
        public string UbbToHtml(string ContentStr)
        {
            PostpramsInfo post = new PostpramsInfo {
                Showimages = 1,
                Smileyoff = 0,
                Sdetail = ContentStr
            };
            return this.UbbToHtml(post);
        }

        /// <summary>
        /// UBB代码处理函数
        /// </summary>
        ///	<param name="_postpramsinfo">UBB转换参数表</param>
        /// <returns>输出字符串</returns>
        public string UbbToHtml(PostpramsInfo _postpramsinfo)
        {
            Match m;
            Match m_1;
            string sDetail = _postpramsinfo.Sdetail.Replace("'", "&acute;").Replace("\"", "&quot;").Replace("<", "&lt;").Replace(">", "&gt;");
            StringBuilder sb = new StringBuilder();
            int pcodecount = -1;
            string sbStr = "";
            string prefix = _postpramsinfo.Pid.ToString();
            if (_postpramsinfo.Bbcodeoff == 0)
            {
                for (m = r[0].Match(sDetail); m.Success; m = m.NextMatch())
                {
                    sbStr = this.Parsecode(m.Groups[1].ToString(), prefix, ref pcodecount, _postpramsinfo.Allowhtml, ref sb);
                    sDetail = sDetail.Replace(m.Groups[0].ToString(), sbStr);
                }
            }
            if (_postpramsinfo.Bbcodeoff == 0)
            {
                sDetail = this.HideDetail(sDetail, _postpramsinfo.Hide, _postpramsinfo.Usercredits);
            }
            sDetail = Regex.Replace(sDetail, @"\[smilie\](.+?)\[\/smilie\]", "$1", options);
            if (_postpramsinfo.Smileyoff == 0)
            {
                sDetail = this.ParseSmilies(sDetail);
            }
            sDetail = Regex.Replace(sDetail, @"\[smilie\](.+?)\[\/smilie\]", "<img src=\"$1\" />", options);
            if (_postpramsinfo.Bbcodeoff == 0)
            {
                if (sDetail.ToLower().Contains("[free]") || sDetail.ToLower().Contains("[/free]"))
                {
                    for (m = r[15].Match(sDetail); m.Success; m = m.NextMatch())
                    {
                        sDetail = sDetail.Replace(m.Groups[0].ToString(), "<br /><div class=\"msgheader\">免费内容:</div><div class=\"msgborder\">" + m.Groups[1].ToString() + "</div><br />");
                    }
                }
                sDetail = Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(sDetail, @"\[b(?:\s*)\]", "<b>", options), @"\[i(?:\s*)\]", "<i>", options), @"\[u(?:\s*)\]", "<u>", options), @"\[/b(?:\s*)\]", "</b>", options), @"\[/i(?:\s*)\]", "</i>", options), @"\[/u(?:\s*)\]", "</u>", options), @"\[sup(?:\s*)\]", "<sup>", options), @"\[sub(?:\s*)\]", "<sub>", options), @"\[/sup(?:\s*)\]", "</sup>", options), @"\[/sub(?:\s*)\]", "</sub>", options), @"((\r\n)*\[p\])(.*?)((\r\n)*\[\/p\])", "<p>$3</p>", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                sDetail = Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(this.ParseUrl(sDetail), @"\[email(?:\s*)\](.*?)\[\/email\]", "<a href=\"mailto:$1\" target=\"_blank\">$1</a>", options), @"\[email=(.[^\[]*)(?:\s*)\](.*?)\[\/email(?:\s*)\]", "<a href=\"mailto:$1\" target=\"_blank\">$2</a>", options), @"\[color=([^\[\<]+?)\]", "<font color=\"$1\">", options), @"\[size=(\d+?)\]", "<font size=\"$1\">", options), @"\[size=(\d+(\.\d+)?(px|pt|in|cm|mm|pc|em|ex|%)+?)\]", "<font style=\"font-size: $1\">", options), @"\[font=([^\[\<]+?)\]", "<font face=\"$1\">", options), @"\[align=([^\[\<]+?)\]", "<p align=\"$1\">", options), @"\[float=(left|right)\]", "<br style=\"clear: both\"><span style=\"float: $1;\">", options), @"\[/color(?:\s*)\]", "</font>", options), @"\[/size(?:\s*)\]", "</font>", options), @"\[/font(?:\s*)\]", "</font>", options), @"\[/align(?:\s*)\]", "</p>", options), @"\[/float(?:\s*)\]", "</span>", options), @"\[indent(?:\s*)\]", "<blockquote>", options), @"\[/indent(?:\s*)\]", "</blockquote>", options), @"\[simpletag(?:\s*)\]", "<blockquote>", options), @"\[/simpletag(?:\s*)\]", "</blockquote>", options), @"\[list\]", "<ul>", options), @"\[list=1\]", "<ul type=1 class=\"litype_1\">", options), @"\[list=a\]", "<ul type=1 class=\"litype_2\">", options), @"\[list=A\]", "<ul type=1 class=\"litype_3\">", options), @"\[\*\]", "<li>", options), @"\[/list\]", "</ul>", options);
                sDetail = Regex.Replace(Regex.Replace(Regex.Replace(this.ParseTable(sDetail), @"(\[SHADOW=)(\d*?),(#*\w*?),(\d*?)\]([\s]||[\s\S]+?)(\[\/SHADOW\])", "<table width='$2'  style='filter:SHADOW(COLOR=$3, STRENGTH=$4)'>$5</table>", options), @"(\[glow=)(\d*?),(#*\w*?),(\d*?)\]([\s]||[\s\S]+?)(\[\/glow\])", "<table width='$2'  style='filter:GLOW(COLOR=$3, STRENGTH=$4)'>$5</table>", options), @"\[center\]([\s]||[\s\S]+?)\[\/center\]", "<center>$1</center>", options);
                MatchCollection mc = r[12].Matches(sDetail);
                foreach (Match match in mc)
                {
                    sDetail = sDetail.Replace(match.Groups[0].Value, this.ParseMedia(match.Groups[1].Value, Utils.StrToInt(match.Groups[2].Value, 0x40), Utils.StrToInt(match.Groups[3].Value, 0x30), match.Groups[4].Value == "1", match.Groups[6].Value));
                }
                if (_postpramsinfo.Customeditorbuttoninfo != null)
                {
                    sDetail = this.ReplaceCustomTag(sDetail, _postpramsinfo.Customeditorbuttoninfo);
                }
                int intQuoteIndexOf = sDetail.ToLower().IndexOf("[quote]");
                int quotecount = 0;
                while (((intQuoteIndexOf >= 0) && (sDetail.ToLower().IndexOf("[/quote]") >= 0)) && (quotecount < 3))
                {
                    quotecount++;
                    sDetail = Regex.Replace(sDetail, @"\[quote\]([\s\S]+?)\[/quote\]", "<table cellpadding=2 cellspacing=1 border=0 WIDTH=100% bgcolor=#CCCCCC align=center  style=FONT-SIZE: 9pt><tr><td bgcolor=#F3F3F3 align=center><table width=100% cellpadding=5 cellspacing=1 border=0><TR><TD >$1</table></table>", options);
                    intQuoteIndexOf = sDetail.ToLower().IndexOf("[quote]", (int) (intQuoteIndexOf + 7));
                }
                sDetail = Regex.Replace(Regex.Replace(sDetail, @"\[area=([\s\S]+?)\]([\s\S]+?)\[/area\]", "<div class=\"msgheader\">$1</div><div class=\"msgborder\">$2</div>", options), @"\[area\]([\s\S]+?)\[/area\]", "<br /><br /><div class=\"msgheader\"></div><div class=\"msgborder\">$1</div>", options);
            }
            if (_postpramsinfo.Parseurloff == 0)
            {
                sDetail = Regex.Replace(Regex.Replace(Regex.Replace(sDetail.Replace("&amp;", "&"), @"^((tencent|ed2k|thunder|vagaa):\/\/[\[\]\|A-Za-z0-9\.\/=\?%\-&_~`@':+!]+)", "<a target=\"_blank\" href=\"$1\">$1</a>", options), @"((tencent|ed2k|thunder|vagaa):\/\/[\[\]\|A-Za-z0-9\.\/=\?%\-&_~`@':+!]+)$", "<a target=\"_blank\" href=\"$1\">$1</a>", options), "[^>=\\]\"]((tencent|ed2k|thunder|vagaa):\\/\\/[\\[\\]\\|A-Za-z0-9\\.\\/=\\?%\\-&_~`@':+!]+)", "<a target=\"_blank\" href=\"$1\">$1</a>", options);
            }
            if (_postpramsinfo.Showimages == 1)
            {
                if (_postpramsinfo.Signature == 1)
                {
                    sDetail = Regex.Replace(Regex.Replace(Regex.Replace(sDetail, @"\[img\]\s*(http://[^\[\<\r\n]+?)\s*\[\/img\]", "<img src=\"$1\" border=\"0\" />", options), @"\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*(http://[^\[\<\r\n]+?)\s*\[\/img\]", "<img src=\"$3\" width=\"$1\" height=\"$2\" border=\"0\" />", options), @"\[image\](http://[\s\S]+?)\[/image\]", "<img src=\"$1\" border=\"0\" />", options);
                }
                else
                {
                    sDetail = Regex.Replace(Regex.Replace(Regex.Replace(sDetail, @"\[img\]\s*(http://[^\[\<\r\n]+?)\s*\[\/img\]", "<img src=\"$1\" border=\"0\" onload=\"thumbImg(this)\" />", options), @"\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*(http://[^\[\<\r\n]+?)\s*\[\/img\]", "<img src=\"$3\" width=\"$1\" height=\"$2\" border=\"0\" onload=\"thumbImg(this)\" />", options), @"\[image\](http://[\s\S]+?)\[/image\]", "<img src=\"$1\" border=\"0\" />", options);
                }
            }
            pcodecount = 0;
            foreach (string str in Utils.SplitString(sb.ToString(), "<>"))
            {
                sDetail = sDetail.Replace("[\tDISCUZ_CODE_" + prefix + "_" + pcodecount.ToString() + "\t]", str);
                pcodecount++;
            }
            sDetail = Regex.Replace(Regex.Replace(sDetail.Replace("\t", "&nbsp; &nbsp; ").Replace("  ", "&nbsp; "), @"\[r/\]", "\r", options), @"\[n/\]", "\n", options);
            for (m = r[9].Match(sDetail); m.Success; m = m.NextMatch())
            {
                sDetail = sDetail.Replace(m.Groups[0].ToString(), "<br />　　" + m.Groups["正文"].ToString());
            }
            if (_postpramsinfo.Allowhtml == 0)
            {
                sDetail = sDetail.Replace("\r\n", "<br />").Replace("\r", "").Replace("\n\n", "<br /><br />").Replace("\n", "<br />").Replace("{rn}", "\r\n").Replace("{nn}", "\n\n").Replace("{r}", "\r").Replace("{n}", "\n");
            }
            Regex r_1 = new Regex(@"(\[FLY\])([ \S\t]*?)(\[\/FLY\])", RegexOptions.IgnoreCase);
            for (m_1 = r_1.Match(sDetail); m_1.Success; m_1 = m_1.NextMatch())
            {
                sDetail = sDetail.Replace(m_1.Groups[0].ToString(), "<MARQUEE width=80% scrollamount=3>" + m_1.Groups[2].ToString() + "</MARQUEE>");
            }
            r_1 = new Regex(@"(\[qq\])([ \S\t]*?)(\[\/qq\])", RegexOptions.IgnoreCase);
            for (m_1 = r_1.Match(sDetail); m_1.Success; m_1 = m_1.NextMatch())
            {
                sDetail = sDetail.Replace(m_1.Groups[0].ToString(), "<a target='new' href='tencent://message/?uin=" + m_1.Groups[2].ToString() + "&Site=www.xinglico.com&Menu=yes'><img border='0' src='http://wpa.qq.com/pa?p=1:" + m_1.Groups[2].ToString() + ":8' alt='点击这里给我发消息'></a>");
            }
            return sDetail;
        }

        /// <summary>
        /// 根路径(/editer/discuz)
        /// </summary>
        public string Root_Path
        {
            get
            {
                return this._Root_Path;
            }
            set
            {
                this._Root_Path = value;
            }
        }
    }
}

